---
title: 存储管理
description: 分区存储管理、分页存储管理、分段存储管理、段页式存储管理
---

存储器的结构：寄存器 —— 高速缓存 Cache —— 主存 —— 外存

地址重定位：将逻辑地址转换为实际主存物理地址的过程，分为静态重定位（在程序存入主存时就完成了转换）、动态重定位（边运行边转换）。
## 分区存储管理

所谓的分区存储组织，就是<RedSpan>整存，将某进程运行所需的内存整体一起分配给它</RedSpan>，然后再运行，有三种分区方式：

### 固定分区
静态分区方法，将主存分为若干个固定的分区，将要运行的作业装配进去，由于分区固定，大小和作业需要的大小不同，会产生内部碎片。
### 可变分区
动态分区方法，主存空间的分区是作业转入时划分，正好划分为作业需要的大小，这样就不存在内部碎片，但容易将整片主存空间切割成许多块，会产生外部碎片，可变分区的算法如下：

系统分配内存的算法有很多，如下图所示，根据分配前的内存情况，还需要分配 9 K 空间，对不同算法的结果介绍如下：
* 首次适应法：按内存地址顺粗从头查找，找到第一个 `>=9K` 空间的空闲块，即切割 9K 空间分配给进程。
* 最佳适应法：按内存中所有空闲内存块按从小到大排序，找到第一个 `>= 9K`空间的空闲块，切割分配，这个将会找到与 `9k` 空间最相近的空闲块。
* 最差适应法：和最佳适应法相反，将内存中空闲块空间最大的，<RedSpan>切割 9K 空间</RedSpan>分配给进程，这是为了 <RedSpan>预防系统中产生过多的细小空闲块。</RedSpan>
* 循环首次适应法：按内存地址顺序查找，找到第一个 `>=` 9K 空间的空闲块，而后若还需分配，则找下一个，<RedSpan>不用每次都从头查找</RedSpan>，这是与首次适应法不同的地方。

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202410281438869.png"/>
### 可重定位分区
可以解决碎片问题，移动所有已经分配好的区域，使其成为一个连续的区域，这样其它外部细小的分区碎片可以合并为大的分区，满足作业要求。只在外部请求空间得不到满足时进行。

## 页式存储管理
如果采用分区管理，都是整存，会出现一个问题，即当 <RedSpan>进程运行所需内存大于系统内存时</RedSpan>，就无法将整个进程一起调入内存，因此无法运行，若要解决此问题，就要采用段页式存储组织，<RedSpan>页式存储是基于可变分区而提出的</RedSpan>。

页式存储组织，将进程空间分成一个个页，假设每个页的大小为 4K，同样的将系统的物理空间也分成一个个 4K 大小的物理块，这样，每次将需要运行的逻辑页装入物理块中，运行完再装入其它需要运行的页，这样就可以分批次运行完进程，而无需将整块逻辑空间全部装入物理内存中，解决了空间极大的进程的运行问题。

<RedSpan>逻辑页分为页号和页内地址</RedSpan>，页内地址就是物理偏移地址，而页号与物理块号并非按序对应的，需要查询页表，才能得知页号对应的物理块号，再用物理块号加上偏移地址才能得出真正运行时的物理地址。

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202410281450856.png"/>

优点：利用率高、碎片小，分配及管理简单。<br/>
缺点: 增加了系统开销，可能产生抖动现象。 <br/>

:::tip
页地址分为页号和页内地址，页号代表当前时第多少页；页内地址只跟页的大小有关，比如 4KB 的页，页内地址就有 $2^12$ 个字节。<br/>
页内地址是不变的，页号是可变的，页表存放的就是逻辑页号和物理块号之间的对应关系。相互转换时，页内偏移量不变。
:::

### 页面置换算法
有时候，进程空间分为 100 个页面，而系统内存只有 10 个内存块，无法全部满足分配，就需要将马上要执行的页面先分配出去，而后根据算法进行淘汰，使 100 个页面能够按执行顺序调入物理块中执行完。

缺页表示需要执行的页不在内存物理块中，需要从外部调入内存，会增加执行时间，因此，缺页数越多，系统效率越低。页面置换算法如下：
* 最优算法：OPT，理论上的算法，无法实现，是在进程执行完后进行的最佳效率计算，用来让其它算法比较差距。原理是选择未来最长时间不被访问的页面置换，这样可以保证未来执行的都是马上要访问的。
* 先进先出算法：FIFO，先调入内存的页先被置换淘汰，会产生 <RedSpan>抖动现象，即分配的页数越多，缺页率可能越多（即效率越高）</RedSpan>。
* 最近最少使用：LRU，在最近的过去，进程执行过程中，过去最少使用的页面被置换淘汰，根据局部性原理，这种方式效率高，且不会产生抖动现象，使用大量计数器，但是没有 LFU 多。
* 淘汰原则：优先淘汰最近未访问的，而后淘汰最近未被修改的页面。

### 快表
快表是一块小容量的级相联存储器，由快速存储器组成，按内容访问，速度快，并且可以从硬件上保证按内容并行查找，一般用来存放当前访问最频繁的少数活动页面的页号。

快表是将页表存于 Cache 中；慢表将页表存于内存上。慢表需要访问两次内存才能取出页，而快表是访问一次 Cache 和一次内存，速度更快。

## 段式存储管理
将进程空间分为一个个段，<RedSpan>每段也有段号和段内地址</RedSpan>，与页式存储管理不同的是，<RedSpan>每段物理大小不同</RedSpan>，分段是根据逻辑整体分段的，因此，段表也与页表的内容不同，页表中直接是逻辑页号对应物理块号，而段表有段长和基址两个属性，才能确定一个逻辑段在物理段中的位置。

<img src="https://wkq-img.oss-cn-chengdu.aliyuncs.com/img/202410281519425.png"/>

优点：多道程序共享内存，各段程序修改互不影响。 <br/>
缺点: 内存利用率低，内存碎片浪费大。

:::tip
分页是根据物理空间划分，每页大小相同；分段是根据逻辑空间划分，每段是一个完整的功能,便于共享，但是大小不同。
:::
### 地址表示
（段号，段内偏移）：其中段内偏移不能超过该段号对应的段长，否则越界错误，而此地址对应的真正内存地址应该是：段号对应的基地址+段内偏移
